package com.ampq;

import com.ampq.pojo.Book;
import com.ampq.pojo.person;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
/**
 * @Auther: fangym
 * @Date: 2018/9/12 17:03
 * @Description: 接收消息  @RabbitHandler可根据具体类型进行接收
 *               接收消息采用手动确认方式 默认是采用自动确认的方式
 *               channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);表示ack确认
 *               channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);表示ack失败但是从队列中移除
 *               channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,true);表示ack失败并重新入列
 *               第三种方式可能导致卡死 重复失败 所以可以重新发送至消息尾部 或者添加到单独的异常队列中  这里模仿的是重新发送入列至尾部
 *               如果没有确认ack，不管是mq还是消费方宕机或者重启，mq都会重新发送
 */
@Component
@RabbitListener(queues = "learn.emps")
public class QueueAch {

    @Autowired
    RabbitTemplate rabbitTemplate;

    @RabbitHandler
    public void processPerson(person per,Channel channel, Message message) throws IOException{
        /*try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
            //丢弃这条消息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
            System.out.println("receiver fail");
        }*/
    }

    @RabbitHandler
    public void processBook(Book book,Channel channel, Message message) throws IOException{

        if(book.getPrice().equals("123")){
            //channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
            System.out.println("模拟业务流程处理失败"+book.getName()+"  "+book.getPrice());
            book.setPrice("456");
            rabbitTemplate.convertAndSend("ExChange.direct","learn.emps",book);
        }else{
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("模拟业务流程处理成功"+book.getName()+"  "+book.getPrice());
        }
    }

    @RabbitHandler
    public void processString(String str,Channel channel, Message message)throws IOException{
        /*try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
            //丢弃这条消息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
            System.out.println("receiver fail");
        }*/
    }
}
